home *** CD-ROM | disk | FTP | other *** search
- /* @(#) $Header: mail_bbs.c,v 1.8 91/06/04 11:34:20 deyke Exp $ */
-
- /* BBS Mail Delivery Agent */
-
- #include <sys/types.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <unistd.h>
-
- #include "global.h"
- #include "mbuf.h"
- #include "transport.h"
- #include "mail.h"
-
- struct mesg {
- int state;
- #define BBS_OPEN_STATE 0
- #define BBS_COMMAND_STATE 1
- #define BBS_SUBJECT_STATE 2
- #define BBS_SEND_STATE 3
- #define BBS_UNLK_STATE 4
- #define BBS_QUIT_STATE 5
- char buf[1024];
- int cnt;
- FILE * fp;
- struct mailsys *sp;
- struct transport_cb *tp;
- };
-
- static void mail_bbs_transaction __ARGS((struct mesg *mp));
- static void mail_bbs_recv_upcall __ARGS((struct transport_cb *tp, int cnt));
- static void mail_bbs_send_upcall __ARGS((struct transport_cb *tp, int cnt));
- static void mail_bbs_state_upcall __ARGS((struct transport_cb *tp));
-
- /*---------------------------------------------------------------------------*/
-
- static void mail_bbs_transaction(mp)
- struct mesg *mp;
- {
-
- char tmp[1024];
- struct mailjob *jp;
- struct stat statbuf;
- struct tm *tm;
-
- jp = mp->sp->jobs;
- switch (mp->state) {
- case BBS_OPEN_STATE:
- if (mp->buf[mp->cnt-1] == '>') {
- nextjob:
- mp->state = BBS_COMMAND_STATE;
- sprintf(tmp,
- "S %s @ %s < %s\n",
- get_user_from_path(jp->to),
- get_host_from_path(jp->to),
- get_user_from_path(jp->from));
- transport_send(mp->tp, qdata(tmp, strlen(tmp)));
- }
- break;
- case BBS_COMMAND_STATE:
- mp->state = BBS_SUBJECT_STATE;
- sprintf(tmp, "%s\n", jp->subject);
- transport_send(mp->tp, qdata(tmp, strlen(tmp)));
- break;
- case BBS_SUBJECT_STATE:
- if (!stat(jp->cfile, &statbuf) && (mp->fp = fopen(jp->dfile, "r"))) {
- mp->state = BBS_SEND_STATE;
- while (fgets(tmp, sizeof(tmp), mp->fp) && *tmp != '\n') ;
- tm = gmtime(&statbuf.st_mtime);
- sprintf(tmp,
- "R:%02d%02d%02d/%02d%02dz @%-6s [WAMPES BBS Mailer]\n",
- tm->tm_year % 100,
- tm->tm_mon + 1,
- tm->tm_mday,
- tm->tm_hour,
- tm->tm_min,
- Hostname);
- transport_send(mp->tp, qdata(tmp, strlen(tmp)));
- } else {
- mp->state = BBS_QUIT_STATE;
- transport_close(mp->tp);
- }
- break;
- case BBS_SEND_STATE:
- break;
- case BBS_UNLK_STATE:
- if (mp->buf[mp->cnt-1] == '>') {
- unlink(jp->cfile);
- unlink(jp->dfile);
- unlink(jp->xfile);
- mp->sp->jobs = jp->next;
- free(jp);
- if (jp = mp->sp->jobs) goto nextjob;
- mp->state = BBS_QUIT_STATE;
- transport_close(mp->tp);
- }
- break;
- case BBS_QUIT_STATE:
- break;
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void mail_bbs_recv_upcall(tp, cnt)
- struct transport_cb *tp;
- int cnt;
- {
-
- int c;
- struct mbuf *bp;
- struct mesg *mp;
-
- mp = (struct mesg *) tp->user;
- mp->sp->state = MS_TALKING;
- transport_recv(tp, &bp, 0);
- while ((c = PULLCHAR(&bp)) != -1)
- if (c == '\n') {
- mp->buf[mp->cnt] = '\0';
- mail_bbs_transaction(mp);
- mp->cnt = 0;
- }
- else if (mp->cnt < sizeof(mp->buf) - 1)
- mp->buf[mp->cnt++] = c;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void mail_bbs_send_upcall(tp, cnt)
- struct transport_cb *tp;
- int cnt;
- {
-
- char *p;
- int c;
- struct mbuf *bp;
- struct mesg *mp;
-
- mp = (struct mesg *) tp->user;
- if (mp->state != BBS_SEND_STATE || cnt <= 0) return;
- if (!(bp = alloc_mbuf(cnt))) return;
- p = bp->data;
- while (p - bp->data < cnt && (c = getc(mp->fp)) != EOF)
- if (c && c != '\004' && c != '\032') *p++ = c;
- if (bp->cnt = p - bp->data)
- transport_send(tp, bp);
- else
- free_p(bp);
- if (c == EOF) {
- fclose(mp->fp);
- mp->fp = 0;
- transport_send(mp->tp, qdata("\032\n", 2));
- mp->state = BBS_UNLK_STATE;
- }
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void mail_bbs_state_upcall(tp)
- struct transport_cb *tp;
- {
- struct mesg *mp;
-
- if (mp = (struct mesg *) tp->user) {
- if (mp->fp) fclose(mp->fp);
- if (!mp->sp->jobs)
- mp->sp->state = MS_SUCCESS;
- else
- mailer_failed(mp->sp);
- free(mp);
- }
- transport_del(tp);
- }
-
- /*---------------------------------------------------------------------------*/
-
- void mail_bbs(sp)
- struct mailsys *sp;
- {
- struct mesg *mp;
-
- mp = calloc(1, sizeof(*mp));
- mp->sp = sp;
- if (mp->tp = transport_open(sp->protocol, sp->address, mail_bbs_recv_upcall, mail_bbs_send_upcall, mail_bbs_state_upcall, (char *) mp)) {
- mp->tp->recv_mode = EOL_LF;
- mp->tp->send_mode = strcmp(sp->protocol, "tcp") ? EOL_CR : EOL_CRLF;
- transport_set_timeout(mp->tp, 3600);
- } else {
- mailer_failed(sp);
- free(mp);
- }
- }
-
-